package com.module.third.qiniu;

import android.location.Location;
import android.media.ExifInterface;
import android.text.TextUtils;
import android.util.Pair;

import com.module.third.GpsUtil;
import com.module.third.ThirdUtil;
import com.module.third.TimeUtils;
import com.qiniu.android.utils.UrlSafeBase64;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;

import javax.crypto.Mac;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

public class QiniuSignUtils {
    private static volatile QiniuConfig qiniuConfig;
    public static volatile String HOST;

    public static void init(QiniuConfig config) {
        qiniuConfig = config;
        HOST = qiniuConfig.host;
    }

    private static QiniuConfig getConfig() {
        if (qiniuConfig == null) {
            synchronized (QiniuConfig.class) {
                if (qiniuConfig == null) {
                    qiniuConfig = new QiniuConfig();
                }
            }
        }
        return qiniuConfig;
    }

    /**
     * 获取上传文件的token
     *
     * @param filePath
     * @param duration   视频时长
     * @param usefulTime token有效时间（单位：秒）
     */
    protected static String getUploadToken(String filePath, long duration, long usefulTime) {
        //构造上传策略
        JSONObject json = new JSONObject();
        long deadline = System.currentTimeMillis() / 1000 + usefulTime;
        String uploadToken = null;
        try {
            ExifInterface exifInterface = new ExifInterface(filePath);
            // 有效时间为一个小时
            json.put("deadline", deadline);
            json.put("scope", getConfig().bucket);
            //上传回调
            JSONObject returnBody = new JSONObject();
            returnBody.put("key", "$(key)");
            returnBody.put("hash", "$(etag)");

            Pair<Integer, Integer> pair = ThirdUtil.getWidth2Height(filePath, duration > 0);
            if (pair != null) {
                returnBody.put("width", pair.first);
                returnBody.put("height", pair.second);
            } else {
                returnBody.put("width", "$(imageInfo.width)");
                returnBody.put("height", "$(imageInfo.height)");
            }

            returnBody.put("size", "$(fsize)");
            String mimeType = getConfig().listener != null ? getConfig().listener.getMimeType(filePath, duration > 0, !(pair != null && pair.first > 0 && pair.second > 0)) : null;
            if (!TextUtils.isEmpty(mimeType)) {
                returnBody.put("mimeType", mimeType);
            } else {
                returnBody.put("mimeType", "$(mimeType)");
            }
            returnBody.put("time", System.currentTimeMillis());
            try {
                //设置拍摄时间
                long time = TimeUtils.date2TimeStamp(exifInterface.getAttribute(ExifInterface.TAG_DATETIME), "yyyy:MM:dd HH:mm:ss");
                if (time == 0) {
                    time = new File(filePath).lastModified();
                }
                returnBody.put("shotTime", time);//拍摄时间
            } catch (JSONException e) {
                e.printStackTrace();
            }
            Location location = null;
            try {
                //地址
                String latValue = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
                String lngValue = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
                String latRef = exifInterface.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
                String lngRef = exifInterface.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);
                //转换成正确的经纬度
                double[] wgs2bd = GpsUtil.wgs2bd(GpsUtil.score2dimensionality(latValue), GpsUtil.score2dimensionality(lngValue));
                location = new Location("");
                location.setLongitude(wgs2bd[1]);
                location.setLatitude(wgs2bd[0]);
                returnBody.put("longitude", location.getLongitude());//经度
                returnBody.put("latitude", location.getLatitude());//纬度
                //取消获取地址，提高上传速度，有上面的经纬度，后续可以根据api去获取
//                Address address = GpsUtil.getAddress(AppManager.getInstance().currentActivity(), location);
//                returnBody.put("country", address.getCountryName());//国际
//                returnBody.put("province", address.getAdminArea());//省
//
//                if (!TextUtils.isEmpty(address.getSubAdminArea())) {
//                    //如果getSubAdminArea不为空，则getSubAdminArea 为城市
//                    returnBody.put("city", address.getSubAdminArea());//城市
//                    returnBody.put("area", address.getLocality());//区
//                } else {
//                    //如果getSubAdminArea为空，则getLocality 为城市
//                    returnBody.put("city", address.getLocality());//城市
//                    returnBody.put("area", address.getSubLocality());//区
//                }

            } catch (Exception e) {
                e.printStackTrace();
            }
            returnBody.put("duration", duration);
            json.put("returnBody", returnBody.toString());
            String encodedPutPolicy = UrlSafeBase64.encodeToString(json.toString().getBytes());
            byte[] sign = hMacSHA1Encrypt(encodedPutPolicy, getConfig().secret_key);
            String encodedSign = UrlSafeBase64.encodeToString(sign);
            uploadToken = getConfig().access_key + ':' + encodedSign + ':' + encodedPutPolicy;
        } catch (JSONException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return uploadToken;
    }

    /**
     * 获取管理文件的token
     */
    public static String getManageToken(String fileName) {
        try {
            String host = "http://rs.qiniu.com";
            String path = "/delete/" + getDelEencodedEntryURI(fileName);
            String url = host + path;
            byte[] sign = hMacSHA1Encrypt(path + "\n", getConfig().secret_key);
            String encodedSign = UrlSafeBase64.encodeToString(sign);
            String authorization = getConfig().access_key + ':' + encodedSign;
            return "QBox " + authorization;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取管理文件的token
     */
    public static String getDelEencodedEntryURI(String fileName) {
        String entryUrl = getConfig().bucket + ":" + fileName;
        String encodedEntryURI = UrlSafeBase64.encodeToString(entryUrl.getBytes());
        return encodedEntryURI;
    }

    private static final String MAC_NAME = "HmacSHA1";
    private static final String ENCODING = "UTF-8";

    /**
     * 使用 HMAC-SHA1 签名方法对对encryptText进行签名
     *
     * @param encryptText 被签名的字符串
     * @param encryptKey  密钥
     * @return
     * @throws Exception
     */
    private static byte[] hMacSHA1Encrypt(String encryptText, String encryptKey)
            throws Exception {
        byte[] data = encryptKey.getBytes(ENCODING);
        // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称
        SecretKey secretKey = new SecretKeySpec(data, MAC_NAME);
        // 生成一个指定 Mac 算法 的 Mac 对象
        Mac mac = Mac.getInstance(MAC_NAME);
        // 用给定密钥初始化 Mac 对象
        mac.init(secretKey);
        byte[] text = encryptText.getBytes(ENCODING);
        // 完成 Mac 操作
        return mac.doFinal(text);
    }
}
